package com.hp.idempotence.v2.controller;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.hp.idempotence.common.Result;


/**
 * 此v2版本 使用token 方式 redis setIfAbsent 原子性来解决幂等问题
 * 
 * 此方式操作步骤
 * v1：
 * 	1. 用户进入提交页面 ，请求后台接口initToken，后台生成一个唯一id (token) 传给前台并 存到redis 中。
 * 	2. 用户带着获取的token 点击提交操作，进入下面的 testSubmit2 方法。 直接redis 删除 key 如果是true 表示 匹配成功，正常操作， 如果是 false 表示 key 不存在。重复提交
 * 
 * 
 * ========================================================================================
 * 
 * v2.如果前台参数中已经有唯一的id 可以不用后台生产token 。 直接用testSubmit3 接口，视具体业务而定。
 * @author Administrator
 *
 */
@RestController
@RequestMapping(value="/v2")
public class SubmitController2 {
	
	@Autowired
	private StringRedisTemplate redisTemplate;
	
	@RequestMapping(value="/initToken")
	public Result initToken(){
		
		String token = UUID.randomUUID().toString();
		redisTemplate.opsForValue().setIfAbsent(token, token, 30, TimeUnit.MINUTES);
		
		return Result.success(token);
	}
	
	
	@RequestMapping(value="/testSubmit2")
	public Result testSubmit2(@RequestParam String token){
		
		//此时 直接用redis 删除 key 如果是true 表示 匹配成功，正常操作， 如果是 false 表示 key 不存在意味着重复提交。
		//此处不建议用 先get 然后处理完后再 delete 操作， 会出现并发问题。 
		Boolean flag = redisTemplate.delete(token);
		
		if(!flag){
			return Result.fail("重复的表单提交，参数:"+token);
		}
		
		//业务操作 todo
		
		return Result.success("数据提交正常！ 参数:"+token);
		
	}
	
	
	@RequestMapping(value="/testSubmit3")
	public Result testSubmit3(@RequestParam String token){
		
		Boolean absent = redisTemplate.opsForValue().setIfAbsent(token, token, 30, TimeUnit.MINUTES);
		
		if(!absent){
			return Result.fail("重复的表单提交，参数:"+token);
		}
		
		redisTemplate.delete(token);
		
		return Result.success("数据提交正常！ 参数:"+token);
		
	}
}
